﻿using System.Threading;
using Caliburn.Micro;
using NthDownload.ViewModels;
using NthDownload.Composition;
using System.ComponentModel.Composition.Hosting;
using NthDownload.BL;
using System.IO;
using NthDownload.Common;
using System.Windows;
using NthDownload.Common.ViewModels;
using System.Windows.Threading;

namespace NthDownload
{
    public class Bootstrapper : Bootstrapper<ShellViewModel>
    {
        #region Override Methods

        protected override void StartRuntime()
        {
            base.StartRuntime();
            IntializePaths();
            InitializeImportService();
        }

        #endregion Override Methods
        
        #region Methods

        /// <summary>
        /// Initializes the import service
        /// </summary>
        private void InitializeImportService()
        {
            //
            // Register a UI synchronization context instance
            //
            ImportService.AddExportedValueToContainer<SynchronizationContext>(new DispatcherSynchronizationContext(Application.Current.Dispatcher));

            //
            // Registers instances of the event aggregator, window manager and navigation service with the import service
            //
            ImportService.AddExportedValueToContainer<IEventAggregator>(new EventAggregator());
            ImportService.AddExportedValueToContainer<IWindowManager>(new WindowManager());

            //
            // Register all exports from referenced assemblies
            //
            ImportService.AddCatalogueToContainer(new AssemblyCatalog(typeof(NthQueue).Assembly));
            ImportService.AddCatalogueToContainer(new AssemblyCatalog(typeof(ViewModelScreenBase).Assembly));
        }

        /// <summary>
        /// Ensures thhat all paths exist and have the correct permissions
        /// </summary>
        private void IntializePaths()
        {
            //
            // Ensure app data path exists
            //
            DirectoryInfo appDataDirectory = new DirectoryInfo(Paths.AppDataPath);
            if (!appDataDirectory.Exists)
            {
                try
                {
                    appDataDirectory.Create();
                }
                catch
                {
                    MessageBox.Show("Unable to create '" + appDataDirectory.FullName + "', please ensure the current user has the required permissions. The application will now close.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                    Application.Current.ShutdownMode = ShutdownMode.OnExplicitShutdown;
                    Application.Current.Shutdown();
                }
            }

            //
            // Ensure data path exists
            //
            DirectoryInfo dataDirectory = new DirectoryInfo(Paths.DataPath);
            if (!dataDirectory.Exists)
            {
                try
                {
                    dataDirectory.Create();
                }
                catch
                {
                    MessageBox.Show("Unable to create '" + dataDirectory.FullName + "', please ensure the current user has the required permissions. The application will now close.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                    Application.Current.ShutdownMode = ShutdownMode.OnExplicitShutdown;
                    Application.Current.Shutdown();
                }
            }

            //
            // Ensure the plugins path exist
            //
            DirectoryInfo pluginsDirectory = new DirectoryInfo(Paths.PluginsPath);
            if (!pluginsDirectory.Exists)
            {
                try
                {
                    pluginsDirectory.Create();
                }
                catch
                {
                    MessageBox.Show("Unable to create '" + pluginsDirectory.FullName + "', please ensure the current user has the required permissions. The application will now close.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                    Application.Current.ShutdownMode = ShutdownMode.OnExplicitShutdown;
                    Application.Current.Shutdown();
                }
            }

            //
            // Ensure the download plugins path exist
            //
            DirectoryInfo downloadPluginsDirectory = new DirectoryInfo(Paths.DownloadPluginsPath);
            if (!downloadPluginsDirectory.Exists)
            {
                try
                {
                    downloadPluginsDirectory.Create();
                }
                catch
                {
                    MessageBox.Show("Unable to create '" + downloadPluginsDirectory.FullName + "', please ensure the current user has the required permissions. The application will now close.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                    Application.Current.ShutdownMode = ShutdownMode.OnExplicitShutdown;
                    Application.Current.Shutdown();
                }
            }

            //
            // Ensure the bandwidth provider plugins path exist
            //
            DirectoryInfo bandwidthProviderPluginsDirectory = new DirectoryInfo(Paths.BandwidthProviderPluginsPath);
            if (!bandwidthProviderPluginsDirectory.Exists)
            {
                try
                {
                    bandwidthProviderPluginsDirectory.Create();
                }
                catch
                {
                    MessageBox.Show("Unable to create '" + bandwidthProviderPluginsDirectory.FullName + "', please ensure the current user has the required permissions. The application will now close.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                    Application.Current.ShutdownMode = ShutdownMode.OnExplicitShutdown;
                    Application.Current.Shutdown();
                }
            }
        }

        #endregion Methods
    }
}
